﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace HRSystem
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        HRSystem.DAL.MapDAL mapDal = new HRSystem.DAL.MapDAL();
        public MainWindow()
        {
            InitializeComponent();
        }

        double x0, y0, zoomNum;//记录底图原点位置和缩放比例
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
        }
        private void GetOrigin(List<Point> lstData)
        {
            #region  获取坐标的最大范围、缩放比、原点位置    
            double width = cvsData1_1.ActualWidth;
            double height = cvsData1_1.ActualHeight;
            double minx = double.MaxValue, miny = double.MaxValue,
                maxx = double.MinValue, maxy = double.MinValue;
            foreach (var p in lstData)
            {
                double x = p.X, y = p.Y;
                if (minx > x)
                {
                    minx = x;
                }
                if (miny > y)
                {
                    miny = y;
                }
                if (maxx < x)
                {
                    maxx = x;
                }
                if (maxy < y)
                {
                    maxy = y;
                }
            }
            //x轴距离
            double w1 = Math.Abs(Math.Abs(maxx - minx));
            //y轴距离
            double h1 = Math.Abs(Math.Abs(maxy - miny));
            zoomNum = width / w1;
            if (h1 * zoomNum > height)
                zoomNum = height / h1;
            x0 = 0 - minx * zoomNum + (width - w1 * zoomNum) / 2;
            y0 = maxy * zoomNum + (height - h1 * zoomNum) / 2;
            #endregion
        }

        private List<Point> lstData1_1;
        private List<Point> lstData2_1;
        DAL.MapDAL.Parameter param = new DAL.MapDAL.Parameter();
        private void GetParameter()
        {
            param =new DAL.MapDAL.Parameter()
            {
                UpAngleShift = double.Parse(tbxUpAngleShift.Text),
                DownAngleShift = double.Parse(tbxDownAngleShift.Text),
                PointDistanceThrold = int.Parse(tbxPointDistanceThrold.Text),
                PointsMinWidth = int.Parse(tbxPointMinWidth.Text),
                PointsMinCount = int.Parse(tbxPointMinCount.Text),
                AreaX = int.Parse(tbxAreaX.Text),
                AreaY = int.Parse(tbxAreaY.Text),
                RimMinCount = int.Parse(tbxRimMinCount.Text),
                LineMinCount = int.Parse(tbxLineMinCount.Text),
                AngleThrold = int.Parse(tbxAngleThrold.Text),
                DownXShift = int.Parse(tbxDownXShift.Text),
                DownYShift = int.Parse(tbxDownYShift.Text),
                UpXShift = int.Parse(tbxUpXShift.Text),
                UpYShift = int.Parse(tbxUpYShift.Text),
                Width = int.Parse(tbxWidth.Text),
                Height = int.Parse(tbxHeight.Text),
                MaxWidth = int.Parse(tbxMaxWidth.Text)
            };
        }
        private void data_select_Click_1(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.DefaultExt = ".txt";
            ofd.Filter = "Text documents (.txt)|*.txt";
            if (ofd.ShowDialog() == true)
            {
                string filename = ofd.FileName;
                tbkFile1.Text = filename;
                GetParameter();
                lstData1_1 = mapDal.GetMapFromTxt(filename, param.UpAngleShift);
                GetOrigin(lstData1_1);
                ShowMap(lstData1_1, cvsData1_1);
            }
        }
        private void data_select_Click_2(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.DefaultExt = ".txt";
            ofd.Filter = "Text documents (.txt)|*.txt";
            if (ofd.ShowDialog() == true)
            {
                string filename = ofd.FileName;
                tbkFile2.Text = filename;
                GetParameter();
                lstData2_1 = mapDal.GetMapFromTxt(filename, param.DownAngleShift);
                ShowMap(lstData2_1, cvsData2_1);
            }
        }

        private void start_Click(object sender, RoutedEventArgs e)
        {
            GetParameter();
            cvsData1_2.Children.Clear(); cvsData1_3.Children.Clear(); cvsMap1_1.Children.Clear(); cvsMap1_2.Children.Clear(); cvsMap1_3.Children.Clear();
            cvsData2_2.Children.Clear(); cvsData2_3.Children.Clear(); cvsMap2_1.Children.Clear(); cvsMap2_2.Children.Clear(); cvsMap2_3.Children.Clear();
            //-1-去噪
            List<Point> lstPoints1_2, lstPoints2_2;
            mapDal.RemoveNoisePoint(lstData1_1, param, out lstPoints1_2);
            mapDal.RemoveNoisePoint(lstData2_1, param, out lstPoints2_2);
            ShowMap(lstPoints1_2, cvsData1_2);
            ShowMap(lstPoints2_2, cvsData2_2);
            //-2-过滤范围
            List<Point> lstPoints1_3, lstPoints2_3;
            mapDal.SelectPoints(lstPoints1_2, param, out lstPoints1_3);
            mapDal.SelectPoints(lstPoints2_2, param, out lstPoints2_3);
            ShowMap(lstPoints1_3, cvsData1_3);
            ShowMap(lstPoints2_3, cvsData2_3);
            //-3-判断特征
            List<List<Point>> lstListPoints1_4, lstListPoints2_4;
            bool blnIsCable1 = mapDal.IsCable(lstPoints1_3, param, out lstListPoints1_4);
            bool blnIsCable2 = mapDal.IsCable(lstPoints2_3, param, out lstListPoints2_4);
            List<Point> lstPoints1_4 = mapDal.ConvertPoints(lstListPoints1_4), lstPoints2_4 = mapDal.ConvertPoints(lstListPoints2_4);
            ShowMap(lstPoints1_4, cvsMap1_1);
            ShowMap(lstPoints2_4, cvsMap2_1);
            if (!blnIsCable1 || !blnIsCable2) return;
            List<Point> lstPoints1_5 = new List<Point>(), lstPoints2_5 = new List<Point>();//转换到同一平面内

            foreach (var pt in lstPoints1_4)
            {
                lstPoints1_5.Add(new Point(pt.X, lstPoints1_4.First().Y));
            }
            foreach (var pt in lstPoints2_4)
            {
                lstPoints2_5.Add(new Point(pt.X, lstPoints2_4.First().Y));
            }
            ShowMap(lstPoints1_5, cvsMap1_2);
            ShowMap(lstPoints2_5, cvsMap2_2);
            List<DAL.MapDAL.LineSegment> lines1 = mapDal.GetLines(lstPoints1_5, param, 1);
            List<DAL.MapDAL.LineSegment> lines2 = mapDal.GetLines(lstPoints2_5, param, 2);
            List<DAL.MapDAL.LineSegment> linesAll = new List<DAL.MapDAL.LineSegment>();
            linesAll.AddRange(lines1); linesAll.AddRange(lines2);
            ShowMap(linesAll, cvsMap1_3);
            int x, y;
            if (mapDal.GetArea(lines1, lines2, param, out x, out y))
            {
                Point p1 = new Point(x - param.Width / 2, y + param.Height / 2);
                Point p2 = new Point(x + param.Width / 2, y + param.Height / 2);
                Point p3 = new Point(x + param.Width / 2, y - param.Height / 2);
                Point p4 = new Point(x - param.Width / 2, y - param.Height / 2);
                linesAll.Add(new DAL.MapDAL.LineSegment(p1, p2));
                linesAll.Add(new DAL.MapDAL.LineSegment(p2, p3));
                linesAll.Add(new DAL.MapDAL.LineSegment(p3, p4));
                linesAll.Add(new DAL.MapDAL.LineSegment(p4, p1));
                //显示结果
                tbkRes.Text = "成功";
                tbkPos.Text = string.Format("X={0},Y={1}", x, y);
                ShowMap(linesAll, cvsMap2_3);
            }
            else
            {
                tbkRes.Text = "失败";
                tbkPos.Text = null;
            }
        }

        private void ShowMap(List<Point> lstData, Canvas cvs)
        {
            //显示
            cvs.Children.Clear();
            for (int i = 0; i < lstData.Count; i++)
            {
                Point pt = mapDal.GetPointOnMap(x0, y0, zoomNum, lstData[i].X, lstData[i].Y);
                Ellipse ep = new Ellipse();
                ep.Stroke = ep.Fill = Brushes.Black;
                ep.Width = ep.Height = 4;
                cvs.Children.Add(ep);
                Canvas.SetLeft(ep, pt.X - 2); Canvas.SetTop(ep, pt.Y - 2);
            }
        }

        private void ShowMap(List<DAL.MapDAL.LineSegment> lstData, Canvas cvs)
        {
            double x0_2 = 0, y0_2 = 0, zoomNum_2 = 0;
            #region  获取坐标的最大范围、缩放比、原点位置    
            double width = cvs.ActualWidth;
            double height = cvs.ActualHeight;
            double minx = double.MaxValue, miny = double.MaxValue,
                maxx = double.MinValue, maxy = double.MinValue;
            foreach (var p in lstData)
            {
                double x = p.BeginPoint.X, y = p.BeginPoint.Y;
                if (minx > x)
                {
                    minx = x;
                }
                if (miny > y)
                {
                    miny = y;
                }
                if (maxx < x)
                {
                    maxx = x;
                }
                if (maxy < y)
                {
                    maxy = y;
                }
                x = p.EndPoint.X; y = p.EndPoint.Y;
                if (minx > x)
                {
                    minx = x;
                }
                if (miny > y)
                {
                    miny = y;
                }
                if (maxx < x)
                {
                    maxx = x;
                }
                if (maxy < y)
                {
                    maxy = y;
                }
            }
            //x轴距离
            double w1 = Math.Abs(Math.Abs(maxx - minx));
            //y轴距离
            double h1 = Math.Abs(Math.Abs(maxy - miny));
            zoomNum_2 = width / w1;
            if (h1 * zoomNum_2 > height)
                zoomNum_2 = height / h1;
            x0_2 = 0 - minx * zoomNum_2 + (width - w1 * zoomNum_2) / 2;
            y0_2 = maxy * zoomNum_2 + (height - h1 * zoomNum_2) / 2;
            #endregion
            //显示
            cvs.Children.Clear();
            for (int i = 0; i < lstData.Count; i++)
            {
                Point p1 = mapDal.GetPointOnMap(x0_2, y0_2, zoomNum_2, lstData[i].BeginPoint.X, lstData[i].BeginPoint.Y);
                Point p2 = mapDal.GetPointOnMap(x0_2, y0_2, zoomNum_2, lstData[i].EndPoint.X, lstData[i].EndPoint.Y);
                Line line = new Line();
                line.X1 = p1.X; line.Y1 = p1.Y;
                line.X2 = p2.X; line.Y2 = p2.Y;
                line.Stroke = line.Fill = Brushes.Green;
                line.StrokeThickness = 4;
                cvs.Children.Add(line);
            }
        }
    }
}
